package pl.gettoknowme.mobile.android.integration;

import java.util.List;

import pl.gettoknowme.mobile.android.model.DBAdapter;
import pl.gettoknowme.mobile.android.model.dao.LocationDAO;
import pl.gettoknowme.mobile.android.model.dbtypes.Integration;
import pl.gettoknowme.mobile.android.model.dbtypes.Location;
import pl.gettoknowme.mobile.android.model.dbtypes.Integration.IntegrationType;
import pl.gettoknowme.mobile.android.network.NetworkException;
import pl.gettoknowme.mobile.android.network.NetworkManager;
import pl.gettoknowme.mobile.android.network.request.impl.LocationHttpRequestWrapper;
import pl.gettoknowme.mobile.android.network.response.HttpResponseWrapper;
import pl.gettoknowme.mobile.android.util.LoggingUtil;
import android.content.Context;

/**
 * Implementacja wykonania wątku integracji lokalizacji
 * @author Michał Kołodziejski
 */
public class LocationIntegrationRunnable implements Runnable {

    protected Context context;
    protected String userId;
    protected Long lastIntegrationTimestamp;
    protected long nowTimestamp;
    
    
    public LocationIntegrationRunnable(Context context, String userId, Long lastIntegrationTimestamp) {
        this.context = context;
        this.userId = userId;
        this.lastIntegrationTimestamp = lastIntegrationTimestamp;
    }
    
    @Override
    public void run() {
        List<Location> locationList = getLocationList();
        nowTimestamp = System.currentTimeMillis();

        // wysłanie
        DBAdapter dbAdapter = DBAdapter.getInstance(context);
        Integration integration = new Integration();
        integration.setIntegrationTime(nowTimestamp);
        integration.setIntegrationType(IntegrationType.LOCATION);
        if(sendAPIRequest(locationList)){
            LoggingUtil.d(this, "API request finished successfully");
            
            // zakończone powodzeniem - zapisujemy info o udanej integracji
            integration.setSuccessful(true);
            dbAdapter.getIntegrationDAO().insert(integration);
            
            // i usuwamy stare lokalizacje
            dbAdapter.getLocationDAO().deleteAll();
            
        } else {
            // zakończone niepowodzeniem - zapisujemy info o udanej integracji
            integration.setSuccessful(false);
            dbAdapter.getIntegrationDAO().insert(integration);
        }
    }

    
    /**
     * Pobiera listę lokalizacji zapisaną w bazie danych
     * @return lista lokalizacji
     */
    private List<Location> getLocationList(){
        DBAdapter dbAdapter = DBAdapter.getInstance(context);
        
        LocationDAO locationDAO = dbAdapter.getLocationDAO();
        List<Location> locationList = locationDAO.getLocationList();
        
        return locationList;
    }
    
    /**
     * Wysyła listę lokalizacji na serwer
     * @param locationList lista lokalizacji do wysłania
     * @return true jeżeli wysłanie powiodło się, false w p.p.
     */
    private boolean sendAPIRequest(List<Location> locationList){
        NetworkManager networkManager = new NetworkManager();
        LocationHttpRequestWrapper requestWrapper = new LocationHttpRequestWrapper(userId, 
                locationList);
        
        HttpResponseWrapper responseWrapper = null;
        try {
            LoggingUtil.d(this, "sending API request in location integration...");
            responseWrapper = networkManager.sendAPIRequest(requestWrapper);
            LoggingUtil.d(this, "API request sent");
            
        } catch (NetworkException e) {
            LoggingUtil.e(this, "NetworkException occured while sending API request", e);
            return false;
        }
        
        return responseWrapper.isSuccessful();
    }
}
